package com.vaifa.expressage.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.vaifa.expressage.domain.*;
import com.vaifa.expressage.service.expressageService;
import com.vaifa.expressage.uits.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Service
public class expressageServiceImpl implements expressageService {

    @Override
    public void importData(MultipartFile file) throws IOException {
        if (Objects.requireNonNull(file.getOriginalFilename()).contains("菜鸟")) {
            CaiAddress(file);
        }
        if (Objects.requireNonNull(file.getOriginalFilename()).contains("寄件详情")) {
            KD100Address(file);
        }
    }

    @Override
    public String AutoData(MultipartFile file) throws IOException {
        // 初始化 Map，存储快递公司和对应的数据列表
        Map<String, List<TRData>> TRDataMap = new HashMap<>();

        // 初始化快递公司列表，可以根据需求动态添加
        List<String> expressCompanies = Arrays.asList("邮政", "京东", "顺丰", "圆通", "极兔");
        expressCompanies.forEach(express -> TRDataMap.put(express, new ArrayList<>()));

        // 使用 EasyExcel 读取文件，并处理每一条数据
        EasyExcel.read(file.getInputStream(), TRData.class, new PageReadListener<TRData>(trDataList -> {
            for (TRData trDatum : trDataList) {
                String express = trDatum.getExpress(); // 获取快递公司名称

                // 根据快递公司名称匹配并添加到对应的 Map 列表中
                boolean matched = TRDataMap.entrySet().stream().anyMatch(entry -> {
                    if (express.contains(entry.getKey())) {
                        entry.getValue().add(trDatum);
                        return true;
                    }
                    return false;
                });

                // 如果没有匹配到任何快递公司，可以根据需求处理（例如，记录日志或放入默认分类）
                if (!matched) {
                    TRDataMap.computeIfAbsent("其他", key -> new ArrayList<>()).add(trDatum);
                }
            }
        })).sheet().doRead();

        // 调用其他方法处理数据
        ExData(TRDataMap);
        return "自动生成完成";
    }

    private static boolean clearDirectory(File directory) {
        // 检查路径是否存在且是一个目录
        if (directory.exists() && directory.isDirectory()) {
            // 列出文件夹中的文件和子目录
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 递归删除文件或文件夹
                    if (file.isDirectory()) {
                        clearDirectory(file); // 递归调用
                    }
                    // 删除文件
                    boolean deleted = file.delete();
                    if (!deleted) {
                        System.out.println("无法删除文件或文件夹: " + file.getAbsolutePath());
                    }
                }
            }
            return true; // 清空完成
        }
        return false; // 目录不存在或者不是一个文件夹
    }

    public void ExData(Map<String, List<TRData>> TRDataMap) {
        // 获取当前工作目录
        String currentDir = System.getProperty("user.dir");
        // 指定文件夹路径
        String cu = System.getProperty("user.home") + "\\Desktop";
        String folderPath = cu + "\\自动生成\\";
        // 创建File对象
        File folder = new File(folderPath);
        // 检查文件夹是否存在
        if (!folder.exists()) {
            // 创建文件夹
            boolean isCreated = folder.mkdirs();
            if (isCreated) {
                System.out.println("文件夹创建成功: " + folder.getAbsolutePath());
            } else {
                System.out.println("文件夹创建失败");
            }
        } else {
            System.out.println("文件夹已经存在: " + folder.getAbsolutePath());
        }
        // 清空文件夹
        boolean result = clearDirectory(folder);
        if (result) {
            System.out.println("文件夹清空成功: " + folder.getAbsolutePath());
        } else {
            System.out.println("文件夹清空失败，可能该路径不存在或无法访问: " + folder.getAbsolutePath());
        }
        TRDataMap.forEach((key, value) -> {
            if (!value.isEmpty()) {
                if (key.contains("邮政")) {
                    try {
                        InputStream exportTemplate = new FileInputStream(currentDir + "\\" + key + ".xlsx");
                        EasyExcel.write(cu + "\\自动生成\\" + key + ".xlsx").excelType(ExcelTypeEnum.XLSX)
                                //是否自动关闭流
                                .withTemplate(exportTemplate).sheet().doFill(value);
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    try {
                        value.forEach(trData -> {
                            if (trData.getWuPin().matches(".*[十九109].*")) {
                                trData.setZhongLiang("5");
                            } else if (trData.getWuPin().matches(".*[五六56].*")) {
                                trData.setZhongLiang("3");
                            } else {
                                trData.setZhongLiang("0");
                            }
                        });
                        InputStream exportTemplate = new FileInputStream(currentDir + "\\" + key + ".xls");
                        EasyExcel.write(cu + "\\自动生成\\" + key + ".xls").excelType(ExcelTypeEnum.XLS)
                                //是否自动关闭流
                                .withTemplate(exportTemplate).sheet().doFill(value);
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
    }

    public void CaiAddress(MultipartFile file) throws IOException {
        List<AddressSel> addressSels = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), CaiNiao.class, new PageReadListener<CaiNiao>(dataList -> {
            for (CaiNiao demoData : dataList) {
                AddressSel addressSel = new AddressSel();
                try {
                    BeanUtils.copyProperties(addressSel, demoData);
                    addressSel.setSjrAddress(demoData.getSjrSF() + demoData.getSjrCS() + demoData.getSjrQ() + demoData.getSjrJD() + demoData.getSjrXXDZ());
                } catch (IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
                addressSel.setExpress("EMS");
                addressSels.add(addressSel);
            }
        })).sheet().doRead();
        Ciao(addressSels);
    }


    public void KD100Address(MultipartFile file) throws IOException {
        List<AddressSel> addressSels = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), KuaiDi100.class, new PageReadListener<KuaiDi100>(dataList -> {
            for (KuaiDi100 kuaiDi100 : dataList) {
                AddressSel addressSel = new AddressSel();
                try {
                    BeanUtils.copyProperties(addressSel, kuaiDi100);
                } catch (IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
                if (kuaiDi100.getExpress().contains("圆通")) {
                    addressSel.setExpress("YTO");
                }
                if (kuaiDi100.getExpress().contains("极兔")) {
                    addressSel.setExpress("JT");
                }
                addressSels.add(addressSel);
            }
        })).sheet().doRead();
        Ciao(addressSels);
    }

    public void Ciao(List<AddressSel> addressSels) {
        String host = "https://jmexpresv2.market.alicloudapi.com";
        String path = "/express/query-v2";
        String method = "POST";
        String appcode = "23f1752520f34273b6b7d4f87d0ae80e";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        List<AddressSel> addressSelList = new ArrayList<>();
        int i = 1;
        for (AddressSel address : addressSels) {
            bodys.put("expressCode", address.getExpress());
            bodys.put("mobile", address.getJjrPhone());
            bodys.put("number", address.getDanHao());
            System.out.println(address.getExpress() + address.getJjrPhone() + address.getDanHao());
            try {
                HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
                Gson gson = new Gson();
                String logisticsStatusDesc = "";
                JsonObject jsonObject = gson.fromJson(EntityUtils.toString(response.getEntity()), JsonObject.class);
                System.out.println(jsonObject);
                if (jsonObject != null) {
                    if (jsonObject.getAsJsonObject("data") != null) {
                        System.out.println(response.toString());
                        System.out.println(response.getEntity());
                        logisticsStatusDesc = jsonObject.getAsJsonObject("data").get("logisticsStatusDesc").getAsString();
                        address.setExpressType(logisticsStatusDesc);
                        addressSelList.add(address);
                        System.out.println("logisticsStatusDesc: " + logisticsStatusDesc + i++);
                    }
                }
                if (jsonObject == null) {
                    logisticsStatusDesc = "未查到物流信息";
                    System.out.println("logisticsStatusDesc: " + logisticsStatusDesc + i++);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String formattedDateTime = now.format(formatter);
        EasyExcel.write("E:\\" + addressSelList.get(0).getExpress() + formattedDateTime + ".xlsx", AddressSel.class).excelType(ExcelTypeEnum.XLSX)
                //是否自动关闭流
                .autoCloseStream(Boolean.TRUE)
                //自动列宽(不太精确)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("快递信息").doWrite(addressSelList);
        log.info("查询结束，文件已经生成！已经查询到的数据有：{}", i - 1);
    }
}
